package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
	"github.com/pikanezi/mapslice"
	_ "github.com/rogpeppe/go-internal/fmtsort"
	"github.com/tealeg/xlsx"
	"log"
	"os"
	"strconv"
)

type Role struct {
	Id     int    `gorm:"primary_key"` //主键id
	Name   string `gorm:"not null"`   //角色名
	Remark string
	Status int
}

type RoleBack struct {
	Id     string `json:"id"`
	Name   string `json:"name"`
	Remark string `json:"remark"`
	Status string `json:"status"`
}

//规定表名
func (Role) TableName() string {
	return "role"
}

var DB *gorm.DB

//初始化并保持连接
func init() {
	var err error
	DB, err = gorm.Open("mysql",
		fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true",
			"root",
			"123456",
			"127.0.0.1",
			"8890",
			"my_test"))

	//    DB.LogMode(true)//打印sql语句
	if err != nil {
		log.Fatalf("database connect is err:%s", err.Error())
	} else {
		log.Print("connect database is success")
	}
	err = DB.DB().Ping()
	if err != nil {
		DB.DB().Close()
		log.Fatalf("Error on opening database connection: %s", err.Error())
	}
}

func main() {
	pageSize := 10
	roleCount,_ := GetRoleCount()
	if roleCount == 0 {
		log.Fatalf("count is %d, exit", 0)
	}
	pageCount := roleCount/pageSize
	for i :=0; i<= pageCount; i++ {
		fileName := strconv.Itoa(i)
		filePath := "./excel/download/" + fileName + ".xlsx"
		go addExcel(pageSize, i * pageSize, filePath)
		log.Printf("for--1：%d", i)
	}
	log.Printf("end--1：%s", "yes")
	ch := make(chan bool)
	<-ch
	log.Printf("end--2：%s", "yes")
	//合并文件
	concatFile()
	return
}

func addExcel(pageSize int, offset int, filePath string) {
	var role RoleBack
	var roleLists []RoleBack
	roleList, _ := GetRoleList(pageSize, offset)

	for i := 0; i < len(roleList); i++ {
		role.Id = strconv.Itoa(roleList[i].Id)
		role.Name = roleList[i].Name
		role.Remark = roleList[i].Remark
		role.Status = strconv.Itoa(roleList[i].Status)
		roleLists = append(roleLists, role)
	}

	id, _ := mapslice.ToStrings(roleLists, "Id")
	name, _ := mapslice.ToStrings(roleLists, "Name")
	remark, _ := mapslice.ToStrings(roleLists, "Remark")
	status, _ := mapslice.ToStrings(roleLists, "Status")
	//
	var file *xlsx.File
	file = xlsx.NewFile()

	var sheet *xlsx.Sheet
	var row *xlsx.Row
	var cell *xlsx.Cell
	sheet, _ = file.AddSheet("Sheet1")
	row = sheet.AddRow()
	cell = row.AddCell()
	cell.Value = "编号"
	cell = row.AddCell()
	cell.Value = "名称"
	cell = row.AddCell()
	cell.Value = "状态"
	cell = row.AddCell()
	cell.Value = "备注"

	//格式化的时候，必须是2006年一月2日
	//在设置时间格式的时候,时间格式的时间一定是2006-01-02 15:04:05,这是个奇葩,必须是这个时间点, 据说是go诞生之日, 记忆方法:6-1-2-3-4-5
	//filePath := "./excel/download/"+string(offset)+".xlsx"

	if FileExist(filePath) == false {
		f, _ := os.Create( filePath )
		defer f.Close()
	}
	for i := 0; i < len(id); i++ {
		row = sheet.AddRow()
		cell = row.AddCell()
		cell.Value = id[i]

		//log.Printf("id：%s", id[i])

		cell = row.AddCell()
		cell.Value = name[i]
		cell = row.AddCell()
		cell.Value = status[i]
		cell = row.AddCell()
		cell.Value = remark[i]
		file.Save(filePath)
	}
	//log.Printf("end：%s", "yes")
	return
}

func concatFile()  {
	return
	////设置路径，文件夹放在main的同级目录下
	//PthSep := string(os.PathSeparator)
	//Pthdir := "./excel/download/"
	//
	//dir, err := ioutil.ReadDir(Pthdir)
	//if err != nil {
	//	fmt.Printf("open dir failed: %s\n", err.Error())
	//}
	//
	////申明合并后的文件
	//var new_file *xlsx.File
	//var new_sheet *xlsx.Sheet
	//new_file = xlsx.NewFile()
	//var new_err error
	//new_sheet, new_err = new_file.AddSheet("Sheet1")
	//
	//for _, fi := range dir {
	//
	//	fmt.Printf("open success: %s\n", Pthdir + PthSep+fi.Name())
	//	if new_err != nil {
	//		fmt.Printf(new_err.Error())
	//	}
	//
	//	//读取文件
	//	xlFile, err := xlsx.OpenFile(Pthdir + PthSep + fi.Name())
	//	if err != nil {
	//		fmt.Printf("open failed: %s\n", err)
	//	}
	//	for _, sheet := range xlFile.Sheets {
	//		fmt.Printf("Sheet Name: %s\n", sheet.Name)
	//		log.Print(sheet.MaxCol)
	//
	//		num := 0
	//		for _, row := range sheet.Cols {
	//			num++
	//			//跳过前5行，将后面的行写入新的文件
	//			if(num > 1){
	//				new_row := new_sheet.AddRow()
	//				new_row.SetHeightCM(1)
	//
	//				for _, cell := range row.Cells {
	//					text := cell.String()
	//					fmt.Printf("%s\n", text)
	//
	//					new_cell := new_row.AddCell()
	//					new_cell.Value = text
	//				}
	//			}
	//		}
	//
	//
	//	}
	//}
	//
	////写入文件
	//new_err = new_file.Save("merge.xlsx")
	//if new_err != nil {
	//	fmt.Printf(new_err.Error())
	//}
}

func FileExist(path string) bool {
	_, err := os.Lstat(path)
	return !os.IsNotExist(err)
}

/**
http://v1.gorm.io/docs/#query
*/
func GetRoleList(limit int, offset int) (rolelist []Role, err error) {
	//err = DB.Find(&rolelist).Error
	err = DB.Limit(limit).Offset(offset).Find(&rolelist).Error
	return rolelist, err
}

func GetRoleCount() (count int, err error) {
	err = DB.Table("role").Count(&count).Error
	return count,err
}

func typeof(v interface{}) string {
	return fmt.Sprintf("%T", v)
}